[2024年版]GuardDutyで様々な検出を発生させるAmazon GuardDuty Testerを簡単に実行できるようにアレンジしてみた
こんにちは、臼田です。
みなさん、GuardDutyで遊んでますか?(挨拶
今回はGuardDutyにいろんな脅威を検出させることができるAmazon GuardDuty Testerを使ってみたのですが、2024年になり色々変わっていたので、簡単に利用できるようにしてみました。
Amazon GuardDuty Testerの2024年の状況
Amazon GuardDuty Testerは2018年ごろからawslabsで公開されているリポジトリです。以前からやってみた記事は以下のようにいろいろあります。
しかし現在のリポジトリは以前の状態から変わっています。amazon-guardduty-testerのリポジトリは今、以下のように表示されています。
残念ながら2024年8月にこのリポジトリはアーカイブされていました。もちろん引き続きツールを利用することはできます。
しかし、もう1つ以前から変わっているところがあります。以下のデプロイ方法を確認してください。
デプロイ方法がCDKを利用する方法に変わっています。これは2024年6月に変更されました。ついでにいろんなGuardDuty Findingsも検出できるようになりました。ちなみにその際にツールの名前もAmazon GuardDuty TesterからGuardDuty Findings Testerに変わっていました。
以前のデプロイは以下のようにCloudFormationテンプレートを使ってデプロイする方式でした。
CDKで展開するのもよいですが、環境の準備が必要になります。
試しにCloudShellの環境から実行してみたのですが、ストレージ容量の問題でデプロイできませんでした。そのため、どのような環境でもお手軽に実行できなくなってしまいました。
というわけで、今回は以前の方式に戻して、CloudFormationテンプレートで展開できるようにしてみます。といっても、直近の変更でそのままテンプレートを利用するだけではうまく動かなくなっていたので、これをアレンジして共有します。
CloudFormationを利用してAmazon GuardDuty Testerを展開する(2024年版)
以前のGuardDuty TesterのテンプレートではセットアップされるEC2内で実行されるスクリプトなどは直接内包せず、GitHubのリポジトリ上にあるファイルを参照するようになっていました。これがmasterを指しているため、現状では利用できません。というわけで以下のように改変しました。(1000行近くあるので閉じておきます)
guardduty-tester-template.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: >-
This template creates the basic VPC infrastructure for an isolated testing
environment. It will deploy a bastion host into the public subnet for a single
Availability Zone so we have a protected point of entry. It will then create a
linux instance with some red team scripts & tools that operate against common
applications that are created in the same private subnet. **WARNING** This
template creates Amazon EC2 instance and related resources. You will be billed
for the AWS resources used if you create a stack from this template.
Metadata:
'AWS::CloudFormation::Interface':
ParameterGroups:
- Label:
default: Network Configuration
Parameters:
- AvailabilityZones
- VPCCIDR
- PrivateSubnet1CIDR
- PublicSubnet1CIDR
- RemoteAccessCIDR
- Label:
default: Amazon EC2 Configuration
Parameters:
- KeyPairName
ParameterLabels:
AvailabilityZones:
default: Availability Zones
KeyPairName:
default: Key Pair Name
PrivateSubnetCIDR:
default: Private Subnet CIDR
PublicSubnetCIDR:
default: Public Subnet CIDR
RemoteAccessCIDR:
default: Allowed Bastion External Access CIDR
VPCCIDR:
default: VPC CIDR
Parameters:
AvailabilityZones:
Description: >-
Availability Zone to use for the subnets in the VPC. You can select many,
but we just use 1 (the first).
Type: 'List<AWS::EC2::AvailabilityZone::Name>'
KeyPairName:
Description: >-
Public/private key pairs allow you to securely connect to your instance
after it launches
Type: 'AWS::EC2::KeyPair::KeyName'
PrivateSubnetCIDR:
AllowedPattern: >-
^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28
Default: 172.16.0.16/28
Description: CIDR block for isolated private subnet.
Type: String
PublicSubnetCIDR:
AllowedPattern: >-
^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28
Default: 172.16.0.0/28
Description: CIDR Block for the public DMZ subnet for secure administrative entry
Type: String
RemoteAccessCIDR:
AllowedPattern: >-
^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x
Default: 0.0.0.0/0
Description: CIDR from which access to bastion is to be permitted
Type: String
VPCCIDR:
AllowedPattern: >-
^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28
Default: 172.16.0.0/27
Description: CIDR Block for the VPC
Type: String
LatestLinuxAMI:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
LatestWindows2022AMI:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: >-
/aws/service/ami-windows-latest/Windows_Server-2022-English-Full-Base
LatestECSOptimizedAMI:
Description: AMI ID
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id
Conditions:
NVirginiaRegionCondition: !Equals
- !Ref 'AWS::Region'
- us-east-1
Resources:
BastionMainLogGroup:
Type: 'AWS::Logs::LogGroup'
SSHMetricFilter:
Type: 'AWS::Logs::MetricFilter'
Properties:
LogGroupName: !Ref BastionMainLogGroup
FilterPattern: ON FROM USER PWD
MetricTransformations:
- MetricName: SSHCommandCount
MetricValue: 1
MetricNamespace: !Join
- /
- - AWSQuickStart
- !Ref 'AWS::StackName'
DHCPOptions:
Type: 'AWS::EC2::DHCPOptions'
Properties:
DomainName: !If
- NVirginiaRegionCondition
- ec2.internal
- !Join
- ''
- - !Ref 'AWS::Region'
- .compute.internal
DomainNameServers:
- AmazonProvidedDNS
VPC:
Type: 'AWS::EC2::VPC'
Properties:
CidrBlock: !Ref VPCCIDR
InstanceTenancy: default
EnableDnsSupport: 'true'
EnableDnsHostnames: 'true'
Tags:
- Key: Name
Value: !Ref 'AWS::StackName'
- Key: CreatedBy
Value: GuardDuty Test Script
VPCDHCPOptionsAssociation:
Type: 'AWS::EC2::VPCDHCPOptionsAssociation'
Properties:
VpcId: !Ref VPC
DhcpOptionsId: !Ref DHCPOptions
InternetGateway:
Type: 'AWS::EC2::InternetGateway'
Properties:
Tags:
- Key: Network
Value: Public
VPCGatewayAttachment:
Type: 'AWS::EC2::VPCGatewayAttachment'
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PrivateSubnet:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PrivateSubnetCIDR
AvailabilityZone: !Select
- '0'
- !Ref AvailabilityZones
Tags:
- Key: Name
Value: Private subnet
- Key: Network
Value: Private
- Key: CreatedBy
Value: GuardDuty Test Script
PublicSubnet:
Type: 'AWS::EC2::Subnet'
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref PublicSubnetCIDR
AvailabilityZone: !Select
- '0'
- !Ref AvailabilityZones
Tags:
- Key: Name
Value: Public subnet
- Key: Network
Value: Public
- Key: CreatedBy
Value: GuardDuty Test Script
MapPublicIpOnLaunch: true
PrivateSubnetRouteTable:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: Private subnet
- Key: Network
Value: Private
PrivateSubnetRoute:
Type: 'AWS::EC2::Route'
Properties:
RouteTableId: !Ref PrivateSubnetRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NATGateway
PrivateSubnetRouteTableAssociation:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref PrivateSubnet
RouteTableId: !Ref PrivateSubnetRouteTable
PublicSubnetRouteTable:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: Public Subnets
- Key: Network
Value: Public
PublicSubnetRoute:
DependsOn: VPCGatewayAttachment
Type: 'AWS::EC2::Route'
Properties:
RouteTableId: !Ref PublicSubnetRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnetRouteTableAssociation:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicSubnetRouteTable
NATEIP:
DependsOn: VPCGatewayAttachment
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
NATGateway:
DependsOn: VPCGatewayAttachment
Type: 'AWS::EC2::NatGateway'
Properties:
AllocationId: !GetAtt
- NATEIP
- AllocationId
SubnetId: !Ref PublicSubnet
BastionHostRole:
Type: 'AWS::IAM::Role'
Properties:
Policies:
- PolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- 'logs:CreateLogStream'
- 'logs:GetLogEvents'
- 'logs:PutLogEvents'
- 'logs:DescribeLogGroups'
- 'logs:DescribeLogStreams'
- 'logs:PutRetentionPolicy'
- 'logs:PutMetricFilter'
- 'logs:CreateLogGroup'
Resource:
!Sub "arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:${BastionMainLogGroup}:*"
Effect: Allow
PolicyName: bastion-cloudwatch-logs-policy
- PolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- 'ec2:AssociateAddress'
- 'ec2:DescribeAddresses'
Resource:
- '*'
Effect: Allow
PolicyName: bastion-eip-policy
Path: /
AssumeRolePolicyDocument:
Statement:
- Action:
- 'sts:AssumeRole'
Principal:
Service:
- ec2.amazonaws.com
Effect: Allow
Version: 2012-10-17
BastionHostProfile:
Type: 'AWS::IAM::InstanceProfile'
Properties:
Roles:
- !Ref BastionHostRole
Path: /
EIP:
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
BastionAutoScalingGroup:
Type: 'AWS::AutoScaling::AutoScalingGroup'
Properties:
LaunchTemplate:
LaunchTemplateId: !Ref BastionLaunchTemplate
Version: !GetAtt BastionLaunchTemplate.LatestVersionNumber
VPCZoneIdentifier:
- !Ref PublicSubnet
MinSize: '1'
MaxSize: '2'
Cooldown: '300'
DesiredCapacity: '1'
Tags:
- Key: Name
Value: LinuxBastion
PropagateAtLaunch: 'true'
- Key: CreatedBy
Value: GuardDuty Test Script
PropagateAtLaunch: 'true'
CreationPolicy:
ResourceSignal:
Count: '1'
Timeout: PT30M
BastionLaunchTemplate:
Type: 'AWS::EC2::LaunchTemplate'
Properties:
LaunchTemplateName: Bastion-Launch-Template
LaunchTemplateData:
KeyName: !Ref KeyPairName
IamInstanceProfile:
Name: !Ref BastionHostProfile
ImageId: !Ref LatestLinuxAMI
SecurityGroupIds:
- !Ref BastionSecurityGroup
InstanceType: t3.micro
UserData: !Base64
'Fn::Join':
- ''
- - |
#!/bin/bash
- |
export PATH=$PATH:/usr/local/bin
- |
yum update -y
- |
yum install nmap -y
- >
yum install -y aws-cfn-bootstrap
- >
curl -L -o /tmp/bastion_bootstrap.sh
https://raw.githubusercontent.com/awslabs/amazon-guardduty-tester/68854573557ede4cc36047361fa04c6447e20e58/bastion_bootstrap.sh
- |
chown root: /tmp/bastion_bootstrap.sh
- |
chmod +x /tmp/bastion_bootstrap.sh
- EIP_LIST="
- !Ref EIP
- ',Null,Null,Null'
- |
"
- CLOUDWATCHGROUP=
- !Ref BastionMainLogGroup
- |+
- /tmp/bastion_bootstrap.sh
- ' --banner '
- >-
https://raw.githubusercontent.com/awslabs/amazon-guardduty-tester/68854573557ede4cc36047361fa04c6447e20e58/artifacts/banner_message.txt
- ' --enable true'
- ' --tcp-forwarding true'
- ' --x11-forwarding false'
- |+
- '/opt/aws/bin/cfn-signal -e $? --stack '
- !Ref 'AWS::StackName'
- ' --resource BastionAutoScalingGroup --region '
- !Ref 'AWS::Region'
- |+
BastionSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Enables SSH Access to Bastion Hosts
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: !Ref RemoteAccessCIDR
RedTeamECSCluster:
Type: 'AWS::ECS::Cluster'
CloudwatchLogsGroup:
Type: 'AWS::Logs::LogGroup'
Properties:
LogGroupName: !Join
- '-'
- - ECSLogGroup
- !Ref 'AWS::StackName'
RetentionInDays: 14
taskdefinition:
Type: 'AWS::ECS::TaskDefinition'
Properties:
Family: !Join
- ''
- - !Ref 'AWS::StackName'
- '-ecs-demo-app'
ContainerDefinitions:
- Name: simple-app
Cpu: '10'
Essential: 'true'
Image: 'httpd:2.4'
Memory: '300'
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref CloudwatchLogsGroup
awslogs-region: !Ref 'AWS::Region'
awslogs-stream-prefix: ecs-demo-app
PortMappings:
- ContainerPort: 80
Command:
- >-
/bin/sh -c "apt update -y && apt install zip -y && echo -n 'X5O!P%@AP[4\PZX54(P^)7CC)7}\$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!\$H+H*' >/tmp/eicar.com && cp /tmp/eicar.com /tmp/eicar.com.txt && zip -j /tmp/eicar_com.zip /tmp/eicar.com && zip -j /tmp/eicarcom2.zip /tmp/eicar_com.zip && sleep infinity"
EntryPoint:
- sh
- '-c'
ECSAutoScalingGroup:
Type: 'AWS::AutoScaling::AutoScalingGroup'
Properties:
VPCZoneIdentifier:
- !Ref PrivateSubnet
LaunchTemplate:
LaunchTemplateId: !Ref ContainerInstances
Version: !GetAtt ContainerInstances.LatestVersionNumber
MinSize: '1'
MaxSize: '1'
DesiredCapacity: '1'
Tags:
- Key: Name
Value: RedTeam
PropagateAtLaunch: "true"
- Key: CreatedBy
Value: GuardDuty Test Script
PropagateAtLaunch: "true"
CreationPolicy:
ResourceSignal:
Timeout: PT15M
UpdatePolicy:
AutoScalingReplacingUpdate:
WillReplace: 'true'
ContainerInstances:
Type: 'AWS::EC2::LaunchTemplate'
DependsOn:
- BasicLinuxTarget
- BasicWindowsTarget
- NATGateway
Properties:
LaunchTemplateName: ContainerInstances-Launch-Template
LaunchTemplateData:
ImageId: !Ref LatestECSOptimizedAMI
SecurityGroupIds:
- !Ref RedTeamSecurityGroup
InstanceType: t3.micro
IamInstanceProfile:
Name: !Ref RedTeamEC2InstanceProfile
KeyName: !Ref KeyPairName
UserData: !Base64
'Fn::Join':
- ''
- - |
#!/bin/bash -xe
- echo ECS_CLUSTER=
- !Ref RedTeamECSCluster
- |2
>> /etc/ecs/ecs.config
- |
export PATH=$PATH:/usr/local/bin:/usr/sbin:/root/.local/bin
- >
echo 'export PATH=/root/.local/bin:/usr/sbin:$PATH' >>
/home/ec2-user/.profile
- |
yum update -y
- >
yum install nmap git python3 python-argparse
gcc gcc-c++ glib2-devel bind-utils wget unzip -y
- >
yum install cmake openssl-devel libX11-devel libXi-devel
libXtst-devel libXinerama-devel libusb-static libusbmuxd-devel
libusbx-devel libusb-devel -y
- |
yum install freerdp freerdp-devel desktop-file-utils -y
- |
- |
pip3 install paramiko
- |
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
- >
export privateIP=`curl -H "X-aws-ec2-metadata-token: $TOKEN"
-v http://169.254.169.254/latest/meta-data/local-ipv4`
- >
curl -L
https://raw.githubusercontent.com/awslabs/amazon-guardduty-tester/68854573557ede4cc36047361fa04c6447e20e58//guardduty_tester.sh
> /home/ec2-user/guardduty_tester.sh
- >
mkdir /home/ec2-user/compromised_keys
/home/ec2-user/domains
/home/ec2-user/passwords
- >
curl -L
https://raw.githubusercontent.com/awslabs/amazon-guardduty-tester/68854573557ede4cc36047361fa04c6447e20e58//artifacts/queries.txt
> /home/ec2-user/domains/queries.txt
- >
curl -L
https://raw.githubusercontent.com/awslabs/amazon-guardduty-tester/68854573557ede4cc36047361fa04c6447e20e58//artifacts/password_list.txt
> /home/ec2-user/passwords/password_list.txt
- >
curl -L
https://raw.githubusercontent.com/awslabs/amazon-guardduty-tester/68854573557ede4cc36047361fa04c6447e20e58//artifacts/never_used_sample_key.foo
> /home/ec2-user/compromised_keys/compromised.pem
- |
FILE="/home/ec2-user/compromised_keys/compromised.pem"
- >
for FILE in {1..20}; do cp
/home/ec2-user/compromised_keys/compromised.pem
/home/ec2-user/compromised_keys/compromised$FILE.pem; done
- echo 'BASIC_LINUX_TARGET="
- !GetAtt
- BasicLinuxTarget
- PrivateIp
- |
"' >> /home/ec2-user/localIps.sh
- echo 'BASIC_WINDOWS_TARGET="
- !GetAtt
- BasicWindowsTarget
- PrivateIp
- |
"' >> /home/ec2-user/localIps.sh
- |
echo -n 'RED_TEAM_INSTANCE="' >> /home/ec2-user/localIps.sh
- >
curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/instance-id
>> /home/ec2-user/localIps.sh
- |
echo '"' >> /home/ec2-user/localIps.sh
- |
echo -n 'RED_TEAM_IP="' >> /home/ec2-user/localIps.sh
- >
curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/local-ipv4 >>
/home/ec2-user/localIps.sh
- |
echo '"' >> /home/ec2-user/localIps.sh
- echo 'BASIC_LINUX_INSTANCE="
- !Ref BasicLinuxTarget
- |
"' >> /home/ec2-user/localIps.sh
- echo 'BASIC_WINDOWS_INSTANCE="
- !Ref BasicWindowsTarget
- |
"' >> /home/ec2-user/localIps.sh
- |
cd /home/ec2-user/
- |
cat << EOF >> users
- |
ec2-user
root
admin
administrator
ftp
www
nobody
EOF
- |
pip3 install cmake
- >
wget https://github.com/vanhauser-thc/thc-hydra/archive/refs/tags/v9.4.zip
-P /home/ec2-user
- >
wget -q -O /home/ec2-user/libssh.tar.xz
https://www.libssh.org/files/0.9/libssh-0.9.4.tar.xz
- |
tar -xvf /home/ec2-user/libssh.tar.xz
- |
cd /home/ec2-user/libssh-0.9.4
- |
mkdir build
- |
cd build
- >
cmake -DUNIT_TESTING=OFF -DCMAKE_INSTALL_PREFIX=/usr
-DCMAKE_BUILD_TYPE=Release ..
- |
make && make install
- |
cd /home/ec2-user
- |
unzip v9.4.zip
- |
cd /home/ec2-user/thc-hydra-9.4
- |
/home/ec2-user/thc-hydra-9.4/configure
- |
make
- |
make install
- |
git clone https://github.com/galkan/crowbar /home/ec2-user/crowbar
- |
chown -R ec2-user: /home/ec2-user
- |
chmod +x /home/ec2-user/guardduty_tester.sh
- |
chmod +x /home/ec2-user/crowbar/crowbar.py
- |
cd /home/ec2-user
- |
wget https://secure.eicar.org/eicar.com
- |
wget https://secure.eicar.org/eicar.com.txt
- |
wget https://secure.eicar.org/eicar_com.zip
- |
wget https://secure.eicar.org/eicarcom2.zip
- |
# Signal the status from cfn-init
yum install -y aws-cfn-bootstrap
- '/opt/aws/bin/cfn-signal -e $? '
- ' --stack '
- !Ref 'AWS::StackName'
- ' --resource ECSAutoScalingGroup '
- ' --region '
- !Ref 'AWS::Region'
- |+
service:
Type: 'AWS::ECS::Service'
Properties:
Cluster: !Ref RedTeamECSCluster
DesiredCount: '1'
TaskDefinition: !Ref taskdefinition
ServiceScalingTarget:
Type: 'AWS::ApplicationAutoScaling::ScalableTarget'
DependsOn: service
Properties:
MaxCapacity: 2
MinCapacity: 1
ResourceId: !Join
- ''
- - service/
- !Ref RedTeamECSCluster
- /
- !GetAtt
- service
- Name
RoleARN: !GetAtt
- AutoscalingRole
- Arn
ScalableDimension: 'ecs:service:DesiredCount'
ServiceNamespace: ecs
ServiceScalingPolicy:
Type: 'AWS::ApplicationAutoScaling::ScalingPolicy'
Properties:
PolicyName: AStepPolicy
PolicyType: StepScaling
ScalingTargetId: !Ref ServiceScalingTarget
StepScalingPolicyConfiguration:
AdjustmentType: PercentChangeInCapacity
Cooldown: 60
MetricAggregationType: Average
StepAdjustments:
- MetricIntervalLowerBound: 0
ScalingAdjustment: 200
RedTeamEC2Role:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
Policies:
- PolicyName: ecs-service
PolicyDocument:
Statement:
- Effect: Allow
Action:
- 'ecs:CreateCluster'
- 'ecs:DeregisterContainerInstance'
- 'ecs:DiscoverPollEndpoint'
- 'ecs:Poll'
- 'ecs:RegisterContainerInstance'
- 'ecs:StartTelemetrySession'
- 'ecs:Submit*'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: '*'
AutoscalingRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- application-autoscaling.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
Policies:
- PolicyName: service-autoscaling
PolicyDocument:
Statement:
- Effect: Allow
Action:
- 'application-autoscaling:*'
- 'cloudwatch:DescribeAlarms'
- 'cloudwatch:PutMetricAlarm'
- 'ecs:DescribeServices'
- 'ecs:UpdateService'
Resource: '*'
RedTeamEC2InstanceProfile:
Type: 'AWS::IAM::InstanceProfile'
Properties:
Path: /
Roles:
- !Ref RedTeamEC2Role
RedTeamSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Enables SSH Access to RedTeam Tools Host
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
SourceSecurityGroupId: !Ref BastionSecurityGroup
- IpProtocol: tcp
FromPort: '53'
ToPort: '53'
CidrIp: !Ref PrivateSubnetCIDR
- IpProtocol: udp
FromPort: '53'
ToPort: '53'
CidrIp: !Ref PrivateSubnetCIDR
- IpProtocol: tcp
FromPort: '5050'
ToPort: '5050'
CidrIp: !Ref PrivateSubnetCIDR
- IpProtocol: icmp
FromPort: '-1'
ToPort: '-1'
SourceSecurityGroupId: !Ref BastionSecurityGroup
BasicLinuxNetInt:
Type: 'AWS::EC2::NetworkInterface'
Properties:
SubnetId: !Ref PrivateSubnet
GroupSet:
- !Ref BasicLinuxSecurityGroup
BasicLinuxSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Enables Admin Access to basic linux hosts
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
SourceSecurityGroupId: !Ref RedTeamSecurityGroup
- IpProtocol: tcp
FromPort: '80'
ToPort: '80'
SourceSecurityGroupId: !Ref RedTeamSecurityGroup
- IpProtocol: tcp
FromPort: '5050'
ToPort: '5050'
SourceSecurityGroupId: !Ref RedTeamSecurityGroup
- IpProtocol: icmp
FromPort: '-1'
ToPort: '-1'
SourceSecurityGroupId: !Ref RedTeamSecurityGroup
BasicLinuxIAMRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess'
BasicLinuxInstanceProfile:
Type: 'AWS::IAM::InstanceProfile'
Properties:
Roles:
- !Ref BasicLinuxIAMRole
Path: /
BasicLinuxTarget:
Type: 'AWS::EC2::Instance'
Properties:
KeyName: !Ref KeyPairName
NetworkInterfaces:
- NetworkInterfaceId: !Ref BasicLinuxNetInt
DeviceIndex: '0'
IamInstanceProfile: !Ref BasicLinuxInstanceProfile
UserData: !Base64
'Fn::Join':
- ''
- - |
#!/bin/bash
- |
export PATH=$PATH:/usr/local/bin
- |
yum update -y
- >
yum install -y httpd24 php70 mysql56-server php70-mysqlnd gcc
openssl-devel* nmap
- |
service httpd start
- >
export LOCAL_HOST=`curl
http://169.254.169.254/latest/meta-data/local-hostname`
- >
wget -O /home/ec2-user/install
https://d1wk0tztpsntt1.cloudfront.net/linux/latest/install
- |
chmod +x /home/ec2-user/install
- |
bash /home/ec2-user/install -u false
InstanceType: t3.micro
AvailabilityZone: !Select
- '0'
- !Ref AvailabilityZones
ImageId: !Ref LatestLinuxAMI
Tags:
- Key: Name
Value: BasicLinuxTarget
- Key: CreatedBy
Value: GuardDuty Test Script
BasicWindowsSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Enables Admin Access to basic windows hosts
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '3389'
ToPort: '3389'
SourceSecurityGroupId: !Ref RedTeamSecurityGroup
- IpProtocol: icmp
FromPort: '-1'
ToPort: '-1'
SourceSecurityGroupId: !Ref RedTeamSecurityGroup
BasicWindowsIAMRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
BasicWindowsInstanceProfile:
Type: 'AWS::IAM::InstanceProfile'
Properties:
Roles:
- !Ref BasicWindowsIAMRole
Path: /
BasicWindowsTarget:
Type: 'AWS::EC2::Instance'
Properties:
KeyName: !Ref KeyPairName
NetworkInterfaces:
- GroupSet:
- !Ref BasicWindowsSecurityGroup
AssociatePublicIpAddress: 'false'
DeviceIndex: '0'
DeleteOnTermination: 'true'
SubnetId: !Ref PrivateSubnet
InstanceType: t3.micro
AvailabilityZone: !Select
- '0'
- !Ref AvailabilityZones
ImageId: !Ref LatestWindows2022AMI
Tags:
- Key: Name
Value: BasicWindowsTarget
- Key: CreatedBy
Value: GuardDuty Test Script
Outputs:
BastionIp:
Description: Elastic IP for Bastion
Value: !Ref EIP
最後の変更前のコミットを参照するように変更しました。
後は適当にこれでCloudFormationスタックを作成することで展開できます。展開したら複数のEC2が作成されますが、RedTeamインスタンスに接続します。外部からSSHで接続する場合にはBastion経由になりますが、以下記事のようなDHMCがあればSession Managerが利用できます。
接続しましょう。
Session Managerの場合にはec2-userではないため、sudo su - ec2-user
してから、実際にGuardDuty Testerを動かす./guardduty_tester.sh
を実行します。
しばらくすると、GuardDutyが脅威を検出してFindingsが生成されます。
まとめ
GuardDuty Testerを2024年でも簡単に利用できるようにしてみました。もちろんCDKが利用できる環境であれば、新しいFindingタイプも含めて利用できますのでそちらもおすすめです。
しかしながら、環境依存少なく実行したい場合などはこちらの方法も便利ですので検討してみてください。